home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-04-07 | 15.1 KB | 625 lines | [TEXT/MPCC] |
- /******************** ***********************/
- //
- // Player PRO 4.4x -- S3M to MADx
- //
- // Version 1.0 - 12.3.95 ANR
- //
- // To use with CodeWarrior 68K or PPC
- //
- // Antoine ROSSET
- // 16 Tranchees
- // 1206 GENEVA
- // SWITZERLAND
- //
- // FAX: (+41 22) 346 11 97
- // Compuserve: 100277,164
- // Internet: rosset@dial.eunet.ch
- //
- /******************** ***********************/
-
- #include "S3M.h"
- #include "MAD.h"
- #include "RDriver.h"
- #include "PPInOut.h"
-
- #if defined(powerc) || defined(__powerc)
- enum {
- PlayerPROPlug = kCStackBased
- | RESULT_SIZE(SIZE_CODE(sizeof(OSErr)))
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof( OSType)))
- | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof( Ptr*)))
- | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof( MADPartition*)))
- | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof( PPInfoRec*)))
- | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof( short**)))
- };
-
- ProcInfoType __procinfo = PlayerPROPlug;
- #else
- #include <A4Stuff.h>
- #endif
-
- short FoundNoteS3M( short Period)
- {
- short NCount = 1;
-
- while( NCount < 85)
- {
- if( Period >= pitchTable[ NCount][ 0])
- {
- return( NCount);
- }
- NCount++;
- }
- return 0;
- }
-
- unsigned long Tdecode32( void *msg_buf)
- {
- unsigned char *buf = msg_buf;
-
- return( (unsigned long) buf[3] << 24) | ( (unsigned long) buf[2] << 16) | ( (unsigned long) buf[ 1] << 8) | ( (unsigned long) buf[0]);
- }
-
- short Tdecode16( void *msg_buf)
- {
- unsigned char *buf = msg_buf;
-
- return ( (short) buf[1] << 8) | ( (short) buf[0]);
- }
-
- struct Command* GetCommand( register short PosX, register short TrackIdX, register struct MusicPattern* tempMusicPat)
- {
- if( PosX < 0) PosX = 0;
- else if( PosX >= tempMusicPat->header.PatternSize) PosX = tempMusicPat->header.PatternSize -1;
-
- return( & (tempMusicPat->Commands[ (tempMusicPat->header.PatternSize * TrackIdX) + PosX]));
- }
-
- void ConvertS3MEffect( Byte B0, Byte B1, Byte *Cmd, Byte *Arg)
- {
- Str255 tStr;
-
- switch( B0 + 0x40)
- {
- /* default:
- NumToString( B0 + 0x40, tStr);
- DebugStr( tStr);
- break;*/
-
- case 'A':
- *Cmd = speedE; *Arg = B1;
- // if( *Arg >= 0x10 || *Arg < 0x1F) *Arg -= 0x10;
- break;
-
- case 'B':
- *Cmd = fastskipE; *Arg = B1;
- break;
-
- case 'C':
- *Cmd = skipE; *Arg = B1;
- break;
-
- case 'D':
- *Cmd = slidevolE; *Arg = B1;
- break;
-
- case 'E':
- *Cmd = upslideE; *Arg = B1;
- break;
-
- case 'F':
- *Cmd = downslideE; *Arg = B1;
- break;
-
- case 'G':
- *Cmd = portamentoE; *Arg = B1;
- break;
-
- case 'H':
- *Cmd = vibratoE; *Arg = B1;
- break;
-
- case 'J':
- *Cmd = arpeggioE; *Arg = B1;
- break;
-
- case 'K':
- *Cmd = vibratoslideE; *Arg = B1;
- break;
-
- case 'O':
- *Cmd = portaslideE; *Arg = B1;
- break;
-
- case 'P':
- *Cmd = offsetE; *Arg = B1;
- break;
-
- case 'S': // Not implemented
- *Cmd = 0; *Arg = 0;
- break;
-
- case 'T': // Not implemented
- *Cmd = 0; *Arg = 0;
- break;
-
- case 'V': // Not implemented
- *Cmd = 0; *Arg = 0;
- break;
-
- case 'X': // Not implemented
- *Cmd = 0; *Arg = 0;
- break;
-
- case 'Z': // Not implemented
- *Cmd = 0; *Arg = 0;
- break;
- }
- }
-
- OSErr ConvertS3M2Mad( Ptr theS3M, long MODSize, MADPartition *theMAD)
- {
- long i, PatMax, x, z, channel, Row;
- long sndSize, OffSetToSample, OldTicks, temp, starting;
- Ptr MaxPtr;
- OSErr theErr;
- Ptr theInstrument[ 64], destPtr;
- Byte tempChar, *theS3MCopy;
- short Note, Octave, maxTrack;
- // short S3Mperiod[ 12] = {1712,1616,1524,1440,1356,1280,1208,1140,1076,1016, 960, 907};
- long note_st3period;
- long note_amigaperiod;
- Byte *ChannelSettings;
-
- /**** Variables pour le MAD ****/
- struct Command *aCmd;
-
- /**** Variables pour le S3M ****/
-
- s3mform s3minfo;
- /********************************/
-
- for( i = 0 ; i < 64; i ++)
- {
- theInstrument[ i] = 0L;
- }
-
- /**** Header principal *****/
- theS3MCopy = (Byte*) theS3M;
- BlockMove( theS3MCopy, &s3minfo, 96);
- theS3MCopy += 96;
-
- s3minfo.ordernum = Tdecode16( &s3minfo.ordernum);
- s3minfo.insnum = Tdecode16( &s3minfo.insnum);
- s3minfo.patnum = Tdecode16( &s3minfo.patnum);
- s3minfo.flags = Tdecode16( &s3minfo.flags);
- s3minfo.cwtv = Tdecode16( &s3minfo.cwtv);
- s3minfo.ffv = Tdecode16( &s3minfo.ffv);
-
- /**** Order Num *****/
- s3minfo.orders = (unsigned char *) NewPtr( s3minfo.ordernum);
- BlockMove( theS3MCopy, s3minfo.orders, s3minfo.ordernum);
- theS3MCopy += s3minfo.ordernum;
-
- /**** Ins Num *****/
- s3minfo.parapins = (unsigned short *) NewPtr( s3minfo.insnum * 2L);
- BlockMove( theS3MCopy, s3minfo.parapins, s3minfo.insnum * 2L);
- theS3MCopy += s3minfo.insnum * 2L;
- for( i = 0; i < s3minfo.insnum; i++)
- {
- s3minfo.parapins[ i] = Tdecode16( &s3minfo.parapins[ i]);
- }
-
-
- /**** Pat Num *****/
- s3minfo.parappat = (unsigned short *) NewPtr( s3minfo.patnum * 2L);
- BlockMove( theS3MCopy, s3minfo.parappat, s3minfo.patnum * 2L);
- theS3MCopy += s3minfo.patnum * 2L;
- for( i = 0; i < s3minfo.patnum; i++)
- {
- s3minfo.parappat[ i] = Tdecode16( &s3minfo.parappat[ i]);
- }
-
- /**** Ins Data ****/
- s3minfo.insdata = (s3minsform *) NewPtr( sizeof(s3minsform) * s3minfo.insnum);
- for (i = 0; i < s3minfo.insnum; i++)
- {
- theS3MCopy = (Byte*) theS3M;
- theS3MCopy += s3minfo.parapins[i]*16L;
-
- BlockMove( theS3MCopy, &s3minfo.insdata[i], sizeof(s3minsform));
-
- s3minfo.insdata[i].insmemseg = Tdecode16( &s3minfo.insdata[i].insmemseg);
- s3minfo.insdata[i].inslength = Tdecode32( &s3minfo.insdata[i].inslength);
- s3minfo.insdata[i].insloopbeg = Tdecode32( &s3minfo.insdata[i].insloopbeg);
- s3minfo.insdata[i].insloopend = Tdecode32( &s3minfo.insdata[i].insloopend);
- s3minfo.insdata[i].insloc2spd = Tdecode16( &s3minfo.insdata[i].insloc2spd);
- s3minfo.insdata[i].inshic2spd = Tdecode16( &s3minfo.insdata[i].inshic2spd);
- s3minfo.insdata[i].insgvspos = Tdecode16( &s3minfo.insdata[i].insgvspos);
- s3minfo.insdata[i].insint512 = Tdecode16( &s3minfo.insdata[i].insint512);
- s3minfo.insdata[i].insintlastused = Tdecode32( &s3minfo.insdata[i].insintlastused);
-
- if (s3minfo.insdata[i].instype == 1)
- {
- theS3MCopy = (Byte*) theS3M;
- theS3MCopy += s3minfo.insdata[i].insmemseg*16L;
-
- theInstrument[ i] = (Ptr) theS3MCopy;
- }
- else theInstrument[ i] = 0L;
- }
-
- /******** Le S3M a été lu et analysé ***********/
- /******** Copie des informations dans le MAD ***/
-
- theMAD->header = (MADSpec*) NewPtrClear( sizeof( MADSpec));
- theMAD->header->MADIdentification = 'MADG';
- for(i=0; i<32; i++) theMAD->header->NameSignature[i] = 0;
- for(i=0; i<28; i++) theMAD->header->NameSignature[i] = s3minfo.name[i];
-
- theMAD->header->PatMax = s3minfo.patnum;
- theMAD->header->numPointers = s3minfo.ordernum;
-
- for(i=0; i<128; i++) theMAD->header->oPointers[ i] = 0;
- for(i=0; i<s3minfo.ordernum; i++)
- {
- theMAD->header->oPointers[ i] = s3minfo.orders[i];
-
- if( theMAD->header->oPointers[ i] < 0 || theMAD->header->oPointers[ i] > s3minfo.patnum) theMAD->header->oPointers[ i] = 0;
- }
-
- /********************/
- /***** INSTRUMENTS *****/
- /********************/
-
- for(i=0; i<s3minfo.insnum; i++)
- {
- for( x = 0; x < 28; x++) theMAD->header->fid[i].Filename[x] = s3minfo.insdata[i].insname[x];
- theMAD->header->fid[i].insSize = s3minfo.insdata[i].inslength;
- theMAD->header->fid[i].fineTune = 0;
- theMAD->header->fid[i].volume = s3minfo.insdata[i].insvol;
- theMAD->header->fid[i].freq = 1;
- theMAD->header->fid[i].amplitude = 8;
- theMAD->header->fid[i].loopStart = s3minfo.insdata[i].insloopbeg;
- theMAD->header->fid[i].loopLenght = s3minfo.insdata[i].insloopend - s3minfo.insdata[i].insloopbeg + 2;
-
- if( theMAD->header->fid[i].insSize > 0)
- {
- theMAD->instrument[i] = NewPtr( theMAD->header->fid[i].insSize);
- BlockMove( theInstrument[i], theMAD->instrument[i], theMAD->header->fid[i].insSize);
-
- destPtr = theMAD->instrument[i];
- for( temp = 0; temp < theMAD->header->fid[i].insSize; temp++)
- {
- *(destPtr + temp) -= 0x80;
- }
- }
- else theMAD->instrument[i] = 0L;
- }
-
- for(i = s3minfo.insnum ; i < MAXINSTRU; i++)
- {
- theInstrument[i] = 0L;
- theMAD->header->fid[i].freq = 1;
- theMAD->header->fid[i].amplitude = 8;
- theMAD->header->fid[i].volume = 64;
- }
- /********************/
-
- /*********************/
- /* Check MaxTrack */
- /*********************/
- maxTrack = 0;
- for( i = 0; i < theMAD->header->PatMax ; i++)
- {
- Row = 0;
-
- theS3MCopy = (Byte*) theS3M;
- theS3MCopy += ( (long) s3minfo.parappat[i] )*16L;
- theS3MCopy++;
-
- while( Row < 64)
- {
- tempChar = *theS3MCopy;
- theS3MCopy++;
-
- if( tempChar == 0) Row++;
- else
- { // Channel
- channel = tempChar;
- channel &= 31;
-
- if( channel > maxTrack) maxTrack = channel;
-
- if( (tempChar & 32) != 0) theS3MCopy += 2L;
- if( (tempChar & 64) != 0) theS3MCopy += 1L;
- if( (tempChar & 128) != 0) theS3MCopy += 2L;
- }
- }
- }
- maxTrack ++;
- /********************/
- /***** TEMPORAIRE ******/
- /********************/
-
- theMAD->header->Tracks = maxTrack;
-
- starting = 0;
-
- for( i = 0; i < MAXPATTERN; i++) theMAD->partition[ i] = 0L;
-
- for( i = 0; i < theMAD->header->PatMax ; i++)
- {
- theMAD->partition[ i] = (struct MusicPattern*) NewPtrClear( sizeof( struct MusicPattern) + theMAD->header->Tracks * 64L * sizeof( struct Command));
- theMAD->partition[ i]->header.PatternSize = 64L;
- theMAD->partition[ i]->header.CompressionMode = 'NONE';
-
- for( x = 0; x < 20; x++) theMAD->partition[ i]->header.PatternName[ x] = 0;
-
- theMAD->partition[ i]->header.PatBytes = 0L;
- theMAD->partition[ i]->header.unused2 = 0L;
-
- MaxPtr = (Ptr) theMAD->partition[ i];
- MaxPtr += sizeof( struct MusicPattern) + theMAD->header->Tracks * 64L * sizeof( struct Command);
-
- Row = 0;
-
- theS3MCopy = (Byte*) theS3M;
- theS3MCopy += ( (long) s3minfo.parappat[i] )*16L;
- theS3MCopy++;
-
- while( Row < 64)
- {
- /*
- BYTE:flag, 0 = end of row
- &31 = channel
- &32 = follows; BYTE:note, BYTE:instrument
- &64 = follows; BYTE:volume
- &128 = follows; BYTE:command, BYTE:info
- */
-
- tempChar = *theS3MCopy;
- theS3MCopy++;
-
- if( tempChar == 0) Row++;
- else
- {
- // Channel
-
- channel = tempChar;
- channel &= 31;
- if( channel >= 0 && channel < theMAD->header->Tracks) z = channel;
- else
- {
- DebugStr("\pOut - Channel");
- }
-
- aCmd = GetCommand( Row, z, theMAD->partition[ i]);
-
- // PERIOD
-
- if( (tempChar & 32) != 0)
- {
- aCmd->AmigaPeriod = theS3MCopy[ 0];
-
- if( ((aCmd->AmigaPeriod & 0xF0) > 0xD0) ||
- ((aCmd->AmigaPeriod & 0x0F) > 0x0B)) aCmd->AmigaPeriod = 0;
- else
- {
- Octave = (aCmd->AmigaPeriod & 0xF0) >> 4;
- Octave -= 2;
- Note = (aCmd->AmigaPeriod & 0x0F);
-
- /*
- note_st3period = (8363L * 16L* (long) ( (long) S3Mperiod[ Note] >> (long) Octave )) / 1712L;
- note_amigaperiod = note_st3period / 4L;
-
- aCmd->AmigaPeriod = FoundNoteS3M( note_amigaperiod);
- */
- aCmd->AmigaPeriod = Octave*12 + Note;
- if( aCmd->AmigaPeriod < 0 || aCmd->AmigaPeriod > 80)
- {
- aCmd->AmigaPeriod = 0;
- }
- }
-
- if( theMAD->instrument[ theS3MCopy[ 1] - 1] != 0) aCmd->InstrumentNo = theS3MCopy[ 1];
-
- theS3MCopy += 2L;
- }
-
- // VOLUME
-
- if( (tempChar & 64) != 0)
- {
- aCmd->EffectCmd = 0x0C;
- aCmd->EffectArg = theS3MCopy[ 0];
-
- if( aCmd->EffectArg > 64) Debugger();
-
- theS3MCopy += 1L;
- }
-
- // PARAMETER
-
- if( (tempChar & 128) != 0)
- {
- if( theS3MCopy[ 0] != 255)
- {
- ConvertS3MEffect( theS3MCopy[ 0], theS3MCopy[ 1], &aCmd->EffectCmd, &aCmd->EffectArg);
- }
- theS3MCopy += 2L;
- }
- }
- }
- }
- aCmd = GetCommand( 0, 0, theMAD->partition[ theMAD->header->oPointers[ 0]]);
- aCmd->EffectCmd = speedE;
- aCmd->EffectArg = s3minfo.initialspeed;
-
- aCmd = GetCommand( 1, 0, theMAD->partition[ theMAD->header->oPointers[ 0]]);
- aCmd->EffectCmd = speedE;
- aCmd->EffectArg = s3minfo.initialtempo;
-
- DisposPtr( (Ptr) s3minfo.orders); DisposPtr( (Ptr) s3minfo.parapins);
- DisposPtr( (Ptr) s3minfo.parappat); DisposPtr( (Ptr) s3minfo.insdata);
-
- return noErr;
- }
-
- void pStrcpy(register unsigned char *s1, register unsigned char *s2)
- {
- register short len, i;
-
- len = *s2;
- for ( i = 0; i <= len; i++) s1[ i] = s2[ i];
- }
-
- OSErr ExtractS3MInfo( PPInfoRec *info, Ptr AlienFile)
- {
- s3mform *myS3M = ( s3mform*) AlienFile;
- long PatternSize;
- short i;
- short maxInstru;
- short tracksNo;
-
- /*** Signature ***/
-
- info->signature = 'S3M ';
-
- /*** Internal name ***/
-
- myS3M->name[ 27] = '\0';
- pStrcpy( info->internalFileName, CtoPstr( myS3M->name));
-
- /*** Total Patterns ***/
-
- info->totalPatterns = 0;
-
- /*** Partition Length ***/
-
- info->partitionLength = 0;
-
- /*** Total Instruments ***/
-
- info->totalInstruments = 0;
-
- pStrcpy( info->formatDescription, "\pS3M Plug");
-
- return noErr;
- }
-
- OSErr TestS3MFile( Ptr AlienFile)
- {
- s3mform *myS3M = ( s3mform*) AlienFile;
-
- if( myS3M->s3msig[ 0] == 'S' &&
- myS3M->s3msig[ 1] == 'C' &&
- myS3M->s3msig[ 2] == 'R' &&
- myS3M->s3msig[ 3] == 'M') return noErr;
- else return fileNotSupportedByThisPlug;
- }
-
- OSErr main( OSType order, FSSpec *AlienFileFSSpec, MADPartition *MadFile, PPInfoRec *info, short *MADpitchTable)
- {
- OSErr myErr;
- Ptr AlienFile;
- short vRefNum, iFileRefI;
- long dirID, sndSize;
-
- #ifndef powerc
- long oldA4 = SetCurrentA4(); //this call is necessary for strings in 68k code resources
- #endif
-
- HGetVol( 0L, &vRefNum, &dirID);
- HSetVol( 0L, AlienFileFSSpec->vRefNum, AlienFileFSSpec->parID);
-
- myErr = noErr;
-
- switch( order)
- {
- case 'IMPL':
- myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
- if( myErr == noErr)
- {
- GetEOF( iFileRefI, &sndSize);
-
- // ** MEMORY Test Start
- AlienFile = NewPtr( sndSize * 2L);
- if( AlienFile == 0L) myErr = needMoreMemory;
- // ** MEMORY Test End
-
- else
- {
- DisposPtr( AlienFile);
-
- AlienFile = NewPtr( sndSize);
- myErr = FSRead( iFileRefI, &sndSize, AlienFile);
- if( myErr == noErr)
- {
- myErr = TestS3MFile( AlienFile);
- if( myErr == noErr)
- {
- myErr = ConvertS3M2Mad( AlienFile, GetPtrSize( AlienFile), MadFile);
- }
- }
- DisposPtr( AlienFile); AlienFile = 0L;
- }
- FSClose( iFileRefI);
- }
- break;
-
- case 'TEST':
- myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
- if( myErr == noErr)
- {
- sndSize = 1024L;
-
- AlienFile = NewPtr( sndSize);
- if( AlienFile == 0L) myErr = needMoreMemory;
- else
- {
- myErr = FSRead( iFileRefI, &sndSize, AlienFile);
- myErr = TestS3MFile( AlienFile);
-
- DisposPtr( AlienFile); AlienFile = 0L;
- }
- FSClose( iFileRefI);
- }
- break;
-
- case 'INFO':
- myErr = FSOpen( AlienFileFSSpec->name, 0, &iFileRefI);
- if( myErr == noErr)
- {
- GetEOF( iFileRefI, &info->fileSize);
-
- sndSize = 5000L; // Read only 5000 first bytes for optimisation
-
- AlienFile = NewPtr( sndSize);
- if( AlienFile == 0L) myErr = needMoreMemory;
- else
- {
- myErr = FSRead( iFileRefI, &sndSize, AlienFile);
- if( myErr == noErr)
- {
- myErr = ExtractS3MInfo( info, AlienFile);
- }
- DisposPtr( AlienFile); AlienFile = 0L;
- }
- FSClose( iFileRefI);
- }
- break;
-
- default:
- myErr = orderNotImplemented;
- break;
- }
-
- HSetVol( 0L, vRefNum, dirID);
-
- #ifndef powerc
- SetA4( oldA4);
- #endif
- return myErr;
- }